Don't put hashes in libraries of the root crate
authorAlex Crichton <alex@alexcrichton.com>
Wed, 29 Apr 2015 17:12:23 +0000 (10:12 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 29 Apr 2015 18:03:21 +0000 (11:03 -0700)
The root crate often has artifacts which are later intended for distribution of
some form, so adding a hash will just make predicting the file name difficult.
The hash also isn't necessary as it's guaranteed to not conflict with other
files (no other dependencies are in the same directory) and all other libraries
have metadata so symbols will not conflict.

Closes #1484

src/cargo/ops/cargo_clean.rs
src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/fingerprint.rs
src/cargo/ops/cargo_rustc/mod.rs
tests/test_cargo_build_lib.rs
tests/test_cargo_compile.rs
tests/test_cargo_compile_custom_build.rs
tests/test_cargo_profiles.rs

index ea25fc509d7a975cb00cdb3fb33117d84c85ec5a..585426cf37b988fecfef5a464a020bd7ca46aa32 100644 (file)
@@ -63,7 +63,7 @@ pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> {
         try!(rm_rf(&layout.fingerprint(&pkg)));
         let profiles = [Profile::default_dev(), Profile::default_test()];
         for profile in profiles.iter() {
-            for filename in try!(cx.target_filenames(target, profile)).iter() {
+            for filename in try!(cx.target_filenames(&pkg, target, profile)).iter() {
                 try!(rm_rf(&layout.dest().join(&filename)));
                 try!(rm_rf(&layout.deps().join(&filename)));
             }
index 3fcf058de96b5be3731209982c63e669ea0663dc..9cfa05a17e415f5a7d5101cbf9237bc4950ad649 100644 (file)
@@ -257,8 +257,8 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
     }
 
     /// Get the metadata for a target in a specific profile
-    pub fn target_metadata(&self, target: &Target, profile: &Profile)
-                           -> Option<Metadata> {
+    pub fn target_metadata(&self, pkg: &Package, target: &Target,
+                           profile: &Profile) -> Option<Metadata> {
         let metadata = target.metadata();
         if target.is_lib() && profile.test {
             // Libs and their tests are built in parallel, so we need to make
@@ -269,19 +269,26 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
             })
         } else if target.is_bin() && profile.test {
             // Make sure that the name of this test executable doesn't
-            // conflicts with a library that has the same name and is
+            // conflict with a library that has the same name and is
             // being tested
-            let mut metadata = self.resolve.root().generate_metadata();
+            let mut metadata = pkg.package_id().generate_metadata();
             metadata.mix(&format!("bin-{}", target.name()));
             Some(metadata)
+        } else if pkg.package_id() == self.resolve.root() && !profile.test {
+            // If we're not building a unit test then the root package never
+            // needs any metadata as it's guaranteed to not conflict with any
+            // other output filenames. This means that we'll have predictable
+            // file names like `target/debug/libfoo.{a,so,rlib}` and such.
+            None
         } else {
             metadata.map(|m| m.clone())
         }
     }
 
     /// Returns the file stem for a given target/profile combo
-    pub fn file_stem(&self, target: &Target, profile: &Profile) -> String {
-        match self.target_metadata(target, profile) {
+    pub fn file_stem(&self, pkg: &Package, target: &Target,
+                     profile: &Profile) -> String {
+        match self.target_metadata(pkg, target, profile) {
             Some(ref metadata) => format!("{}{}", target.crate_name(),
                                           metadata.extra_filename),
             None if target.allows_underscores() => target.name().to_string(),
@@ -291,9 +298,9 @@ impl<'a, 'b: 'a> Context<'a, 'b> {
 
     /// Return the filenames that the given target for the given profile will
     /// generate.
-    pub fn target_filenames(&self, target: &Target, profile: &Profile)
-                            -> CargoResult<Vec<String>> {
-        let stem = self.file_stem(target, profile);
+    pub fn target_filenames(&self, pkg: &Package, target: &Target,
+                            profile: &Profile) -> CargoResult<Vec<String>> {
+        let stem = self.file_stem(pkg, target, profile);
         let suffix = if target.for_host() {&self.host_exe} else {&self.target_exe};
 
         let mut ret = Vec::new();
index 2dacbb3d6904dadfdee8338de45b9af47847657d..ecc62f025b65b30e9f5e7faeb42f8ac8c2d15340 100644 (file)
@@ -57,7 +57,7 @@ pub fn prepare_target<'a, 'b>(cx: &mut Context<'a, 'b>,
     let root = cx.out_dir(pkg, kind, target);
     let mut missing_outputs = false;
     if !profile.doc {
-        for filename in try!(cx.target_filenames(target, profile)).iter() {
+        for filename in try!(cx.target_filenames(pkg, target, profile)).iter() {
             missing_outputs |= fs::metadata(root.join(filename)).is_err();
         }
     }
index 5617135d9cacb362cc90db07b742b4dd9c723ee6..c9c7a02accea58a13e64bd1bdd67e622f069378a 100644 (file)
@@ -133,7 +133,7 @@ pub fn compile_targets<'a, 'b>(targets: &[(&'a Target, &'a Profile)],
     cx.compilation.extra_env.insert("OUT_DIR".to_string(), out_dir);
 
     for &(target, profile) in targets {
-        for filename in try!(cx.target_filenames(target, profile)).iter() {
+        for filename in try!(cx.target_filenames(pkg, target, profile)).iter() {
             let dst = cx.out_dir(pkg, Kind::Target, target).join(filename);
             if profile.test {
                 cx.compilation.tests.push((target.name().to_string(), dst));
@@ -154,7 +154,7 @@ pub fn compile_targets<'a, 'b>(targets: &[(&'a Target, &'a Profile)],
                 if profile.doc { continue }
                 if cx.compilation.libraries.contains_key(&pkgid) { continue }
 
-                let v = try!(cx.target_filenames(target, profile));
+                let v = try!(cx.target_filenames(pkg, target, profile));
                 let v = v.into_iter().map(|f| {
                     (target.clone(),
                      cx.out_dir(pkg, Kind::Target, target).join(f))
@@ -342,7 +342,7 @@ fn rustc(package: &Package, target: &Target, profile: &Profile,
         }
         let exec_engine = cx.exec_engine.clone();
 
-        let filenames = try!(cx.target_filenames(target, profile));
+        let filenames = try!(cx.target_filenames(package, target, profile));
         let root = cx.out_dir(package, kind, target);
 
         // Prepare the native lib state (extra -L and -l flags)
@@ -367,7 +367,7 @@ fn rustc(package: &Package, target: &Target, profile: &Profile,
         let rustc_dep_info_loc = if do_rename {
             root.join(&crate_name)
         } else {
-            root.join(&cx.file_stem(target, profile))
+            root.join(&cx.file_stem(package, target, profile))
         }.with_extension("d");
         let dep_info_loc = fingerprint::dep_info_loc(cx, package, target,
                                                      profile, kind);
@@ -678,7 +678,7 @@ fn build_base_args(cx: &Context,
         None => {}
     }
 
-    match cx.target_metadata(target, profile) {
+    match cx.target_metadata(pkg, target, profile) {
         Some(m) => {
             cmd.arg("-C").arg(&format!("metadata={}", m.metadata));
             cmd.arg("-C").arg(&format!("extra-filename={}", m.extra_filename));
@@ -753,7 +753,7 @@ fn build_deps_args(cmd: &mut CommandPrototype,
             Kind::Target => Kind::Target,
         });
 
-        for filename in try!(cx.target_filenames(target, profile)).iter() {
+        for filename in try!(cx.target_filenames(pkg, target, profile)).iter() {
             if filename.ends_with(".a") { continue }
             let mut v = OsString::new();
             v.push(&target.crate_name());
index e26f0903321a25f31cb31f28dc0e0dfb59d24ff0..763fd0c1711b90eb5bcab3fddb3a56b98888e85a 100644 (file)
@@ -10,8 +10,6 @@ fn verbose_output_for_lib(p: &ProjectBuilder) -> String {
     format!("\
 {compiling} {name} v{version} ({url})
 {running} `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \
-        -C metadata=[..] \
-        -C extra-filename=-[..] \
         --out-dir {dir}{sep}target{sep}debug \
         --emit=dep-info,link \
         -L dependency={dir}{sep}target{sep}debug \
index 3faea78b519c896e99ae43b1c7d7e4dada8b4f69..dad9576635a37ae6e27b38ce7f937c18eda9e5ba 100644 (file)
@@ -842,8 +842,6 @@ test!(verbose_build {
                 execs().with_status(0).with_stdout(&format!("\
 {compiling} test v0.0.0 ({url})
 {running} `rustc src[..]lib.rs --crate-name test --crate-type lib -g \
-        -C metadata=[..] \
-        -C extra-filename=-[..] \
         --out-dir {dir}[..]target[..]debug \
         --emit=dep-info,link \
         -L dependency={dir}[..]target[..]debug \
@@ -871,8 +869,6 @@ test!(verbose_release_build {
 {compiling} test v0.0.0 ({url})
 {running} `rustc src[..]lib.rs --crate-name test --crate-type lib \
         -C opt-level=3 \
-        -C metadata=[..] \
-        -C extra-filename=-[..] \
         --out-dir {dir}[..]target[..]release \
         --emit=dep-info,link \
         -L dependency={dir}[..]target[..]release \
@@ -925,8 +921,6 @@ test!(verbose_release_build_deps {
 {compiling} test v0.0.0 ({url})
 {running} `rustc src[..]lib.rs --crate-name test --crate-type lib \
         -C opt-level=3 \
-        -C metadata=[..] \
-        -C extra-filename=-[..] \
         --out-dir {dir}[..]target[..]release \
         --emit=dep-info,link \
         -L dependency={dir}[..]target[..]release \
@@ -1621,6 +1615,30 @@ cyclic package dependency: package `foo v0.0.1 ([..])` depends on itself
 "));
 });
 
+test!(predictable_filenames {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [lib]
+            name = "foo"
+            crate-type = ["staticlib", "dylib", "rlib"]
+        "#)
+        .file("src/lib.rs", "");
+
+    assert_that(p.cargo_process("build").arg("-v"),
+                execs().with_status(0));
+    assert_that(&p.root().join("target/debug/libfoo.a"), existing_file());
+    assert_that(&p.root().join("target/debug/libfoo.rlib"), existing_file());
+    let dylib_name = format!("{}foo{}", env::consts::DLL_PREFIX,
+                             env::consts::DLL_SUFFIX);
+    assert_that(&p.root().join("target/debug").join(dylib_name),
+                existing_file());
+});
+
 test!(dashes_to_underscores {
     let p = project("foo")
         .file("Cargo.toml", r#"
index d5fc4057ab51d7467de799e1b6440fc0a1b56986..5747b7b2483fc14dffdc6f54749752447324a945 100644 (file)
@@ -768,7 +768,6 @@ test!(build_cmd_with_a_build_cmd {
     --extern a=[..]liba-[..].rlib`
 {running} `[..]foo-[..]build-script-build[..]`
 {running} `rustc [..]lib.rs --crate-name foo --crate-type lib -g \
-    -C metadata=[..] -C extra-filename=-[..] \
     --out-dir [..]target[..]debug --emit=dep-info,link \
     -L [..]target[..]debug -L [..]target[..]deps`
 ", compiling = COMPILING, running = RUNNING)));
index c6760ae2dc3a71bf54523ecd534171f0cbcc7da7..b41d4e851d7de6aa18e887c6cb618187a2eaefa2 100644 (file)
@@ -30,8 +30,6 @@ test!(profile_overrides {
 {running} `rustc src{sep}lib.rs --crate-name test --crate-type lib \
         -C opt-level=1 \
         -C debug-assertions=on \
-        -C metadata=[..] \
-        -C extra-filename=-[..] \
         -C rpath \
         --out-dir {dir}{sep}target{sep}debug \
         --emit=dep-info,link \
@@ -95,8 +93,6 @@ test!(top_level_overrides_deps {
 {running} `rustc src{sep}lib.rs --crate-name test --crate-type lib \
         -C opt-level=1 \
         -g \
-        -C metadata=[..] \
-        -C extra-filename=-[..] \
         --out-dir {dir}{sep}target{sep}release \
         --emit=dep-info,link \
         -L dependency={dir}{sep}target{sep}release \